﻿using System;
using System.Linq;
using System.Threading.Tasks;
using System.Transactions;
using Elsa.Services.Models;
using HengTong.Model;
using HengTong.Model.Db.Hr.Attendance;
using HengTong.Model.Request;
using Microsoft.EntityFrameworkCore;
using TiaoTaoHelper.Wtm.Interfaces;
using TiaoTaoHelper.Wtm.Models;
using TiaoTaoHelper.Wtm.Workflow;
using WalkingTec.Mvvm.Core;
using WalkingTec.Mvvm.Core.WorkFlow;

namespace HengTong.ViewModel.Daily.SysDailyCompOffRequestBillVms;

public partial class SysDailyCompOffRequestBillVm
{
    [WorkflowOperation("驳回", "将单据状态设置为草稿", "调休申请")]
    public async Task Reject(ActivityExecutionContext context)
    {
        Entity.BillStatus = BillStatus.草稿;
        if (Entity is IBasePoco poco)
        {
            poco.UpdateTime = DateTime.Now;
            DC.UpdateProperty(Entity, x => x.UpdateTime);
            if (context.Input is WtmApproveInput input)
            {
                poco.UpdateBy = input.CurrentUser?.ITCode ?? "workflow";
                DC.UpdateProperty(Entity, x => x.UpdateBy);
            }
        }

        DC.UpdateProperty(Entity, x => x.BillStatus);
        await DC.SaveChangesAsync();
    }

    [WorkflowOperation("取消", "将流程状态设置为取消", "调休申请")]
    public async Task Cancel(ActivityExecutionContext context)
    {
        if (Entity is IBasePoco poco)
        {
            poco.UpdateTime = DateTime.Now;
            DC.UpdateProperty(Entity, x => x.UpdateTime);
            if (context.Input is WtmApproveInput input)
            {
                poco.UpdateBy = input.CurrentUser?.ITCode ?? "workflow";
                DC.UpdateProperty(Entity, x => x.UpdateBy);
            }
        }

        if (Entity is IBill bill)
        {
            bill.WorkflowStatus = WorkflowStatus.已取消;
            DC.UpdateProperty(Entity, x => x.WorkflowStatus);
        }

        await DC.SaveChangesAsync();
    }


    // 调休完成事件，委托到人工排班，ShiftType=调休
    [WorkflowOperation("调休处理", "将流程状态设置为已完成并调用人工排班接口", "调休申请")]
    public async Task Complete(ActivityExecutionContext context)
    {
        string currentUser = "workflow";
        if (context.Input is WtmApproveInput input)
            currentUser = input.CurrentUser?.ITCode ?? "workflow";

        using var scope = new TransactionScope(
            TransactionScopeOption.Required,
            new TransactionOptions
                { IsolationLevel = IsolationLevel.ReadCommitted, Timeout = TimeSpan.FromMinutes(10) },
            TransactionScopeAsyncFlowOption.Enabled);

        try
        {
            if (Entity.PersonId == null || Entity.StartTime == null || Entity.EndTime == null)
            {
                MSD.AddModelError(" ", "单据数据不完整");
                return;
            }

            var start = Entity.StartTime.Value.Date;
            var endExclusive = Entity.EndTime.Value.Date;

            var req = new AddAttendanceRecordsRequest
            {
                PersonIds = new[] { Entity.PersonId.Value },
                ShiftType = ShiftAction.调休,
                DateRange = new DateRange(start, endExclusive),
                AutoCalculateFuture = false,
                AttendanceShiftGroupId = null
            };

            var vm = Wtm.CreateVM<HengTong.ViewModel.Hr.SysAttendanceRecordVms.SysAttendanceRecordBatchVm>();
            var ok = await vm.DoBatchAddAsync(req, ScheduleTypeEnum.流程排班, Entity.ID);
            if (!ok)
            {
                MSD.AddModelError(" ", "人工排班处理失败");
                return;
            }

            if (Entity.CompOffType == CompOffType.等时调休)
            {
                if (Entity.CompOffOvertimeLinks == null || !Entity.CompOffOvertimeLinks.Any())
                {
                    MSD.AddModelError(" ", "等时调休必须关联加班记录");
                    return;
                }

                var overtimeIds = Entity.CompOffOvertimeLinks.Select(x => x.OvertimeRequestBillId).ToList();
                var overtimeRecords = await DC.Set<Model.Db.Hr.Bill.SysDailyOvertimeRequestBill>()
                    .Where(x => overtimeIds.Contains(x.ID))
                    .ToListAsync();

                if (overtimeRecords.Count != overtimeIds.Count)
                {
                    MSD.AddModelError(" ", "部分加班记录不存在");
                    return;
                }

                // 扣减剩余可调休小时数
                foreach (var link in Entity.CompOffOvertimeLinks)
                {
                    var record = overtimeRecords.FirstOrDefault(x => x.ID == link.OvertimeRequestBillId);
                    if (record == null)
                    {
                        MSD.AddModelError(" ", $"加班记录{link.OvertimeRequestBillId}不存在");
                        return;
                    }

                    // 检查剩余可调休小时数是否足够
                    /*if (record.RemainingCompOffHours < link.HoursUsed)
                    {
                        MSD.AddModelError(" ",
                            $"加班记录{record.BillCode}的剩余可调休小时数不足,可用:{record.RemainingCompOffHours}小时");
                        return;
                    }*/
                    // 修改为只要剩余大于0即可扣减
                    if (record.RemainingCompOffHours <= 0)
                    {
                        MSD.AddModelError(" ",
                            $"加班记录{record.BillCode}的剩余可调休小时数不足,可用:{record.RemainingCompOffHours}小时");
                        return;
                    }

                    var newRemaining = record.RemainingCompOffHours.GetValueOrDefault() - link.HoursUsed;
                    record.RemainingCompOffHours = newRemaining < 0 ? 0 : newRemaining;
                    DC.UpdateEntity(record);
                }
            }


            if (Entity is IBasePoco poco)
            {
                poco.UpdateTime = DateTime.Now;
                poco.UpdateBy = currentUser;
                DC.UpdateProperty(Entity, x => x.UpdateTime);
                DC.UpdateProperty(Entity, x => x.UpdateBy);
            }

            if (Entity is IBill bill)
            {
                bill.WorkflowStatus = WorkflowStatus.已完成;
                DC.UpdateProperty(Entity, x => x.WorkflowStatus);
            }

            await DC.SaveChangesAsync();
            scope.Complete();
        }
        catch (Exception e)
        {
            MSD.AddModelError(" ", $"完成调休申请失败: {e.Message}");
        }
    }
}